#!/bin/bash
############################################################################
# Copyright (C) 2011 Lawrence Livermore National Security, LLC
# Produced at Lawrence Livermore National Laboratory.
# Written by Jim Garlick <garlick@llnl.gov>.
# UCRL-CODE-235119
# 
# This file is part of nfsroot, a network root file system utility.
# 
# nfsroot is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# nfsroot is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with nfsroot; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
############################################################################
#
# nfsroot-setdefault - change the default kernel
#
PATH=/sbin:/usr/sbin:/bin/:/usr/bin
prog=nfsroot-setdefault
kdir=/boot

usage () {
   echo "Usage: $prog [OPTIONS]" >&2
   echo "  -d kver      sets the default to kver" >&2
   echo "  -r kver      sets the default to something other than kver" >&2
   echo "  -x           remove the current default" >&2
   echo "With no arguments, just make sure there is a valid default." >&2
   exit 1
}

setdefault () {
   local kver=$1
   echo "${prog}: DEFAULT set to $kver" >&2
   ln -sf vmlinuz-$kver ${kdir}/vmlinuz
   ln -sf initramfs-$kver.img ${kdir}/initramfs
   echo "Boot options (default = *)": >$kdir/pxelinux.msg
   configpxe -l | sed -e "s/$kver/$kver (*)/">>$kdir/pxelinux.msg
   return 0
}

clrdefault () {
   rm -f ${kdir}/vmlinuz
   rm -f ${kdir}/initramfs
}

chkver () {
   local kver=$1
   [ -e $kdir/vmlinuz-$kver ] || return 1
   [ -e $kdir/initramfs-$kver.img ] || return 1
   return 0
}

listavail () {
   local file kver
   shopt -s nullglob
   for file in $kdir/vmlinuz-*; do
      kver=$(basename $file|sed -e 's/vmlinuz-//')
      chkver $kver && echo $kver
   done
   shopt -u nullglob
}

curdefault () {
   local file
   file=$(readlink -e $kdir/vmlinuz) || return 1
   basename $file|sed -e 's/vmlinuz-//'
   return 0
}

choosenew () {
   local nker=$1   # if set, chose anything but
   local ver newver

   for ver in $(listavail); do
      if [ -z "$nker" ] || [ "$ver" != "$nker" ]; then
         newver=$ver
      fi
   done
   echo $newver
}

dopt=0
ropt=0
xopt=0
while getopts d:r:x opt; do
   case "$opt" in
      d) dopt=1; kver=$OPTARG ;;
      r) ropt=1; kver=$OPTARG ;;
      x) xopt=1 ;;
      *) usage ;;
   esac
done
shift $(($OPTIND-1))
if [ $# != 0 ]; then
   usage
fi

if ! [ -x /usr/sbin/nfsroot-setdefault ]; then
   echo "${prog}: run me chrooted in root image on the server" >&2
   exit 1
fi

if [ $dopt -eq 1 ]; then
   if ! chkver $kver; then
      echo "$prog: $kver is an invalid kernel selection" >&2
      exit 1
   fi
   setdefault $kver
elif [ $ropt -eq 1 ];then
   if [ "$(curdefault)" = "$kver" ]; then
      kver=$(choosenew $kver)
   else
      kver=$(curdefault)
   fi
   if [ -z "$kver" ]; then
      echo "$prog: no kernel available as DEFAULT" >&2
      exit 1
   fi
   setdefault $kver
elif [ $xopt -eq 1 ];then
   clrdefault
else
   kver=$(curdefault)
   if [ -z "$kver" ]; then
      kver=$(choosenew)
   fi
   if [ -z "$kver" ]; then
      echo "$prog: no kernel available as DEFAULT" >&2
      exit 1
   fi
   setdefault $kver
fi

exit 0
